home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / pine / osdep / sendmail < prev    next >
Text File  |  1996-05-02  |  6KB  |  249 lines

  1. /*----------------------------------------------------------------------
  2.     Routines used to hand off messages to local agents for sending/posting
  3.  
  4.  The two exported routines are:
  5.  
  6.     1) smtp_command()  -- used to get local transport agent to invoke
  7.     2) post_handoff()  -- used to pass messages to local posting agent
  8.  
  9.  ----*/
  10.  
  11.  
  12.  
  13. /*
  14.  * Protos for "sendmail" internal functions
  15.  */
  16. static char *mta_parse_post PROTO((METAENV *, BODY *, char *, char *));
  17. static long  pine_pipe_soutr_nl PROTO((void *, char *));
  18.  
  19.  
  20.  
  21. /* ----------------------------------------------------------------------
  22.    Figure out command to start local SMTP agent
  23.  
  24.   Args: errbuf   -- buffer for reporting errors (assumed non-NULL)
  25.  
  26.   Returns an alloc'd copy of the local SMTP agent invocation or NULL
  27.  
  28.   ----*/
  29. char *
  30. smtp_command(errbuf)
  31.     char *errbuf;
  32. {
  33. #if    defined(SENDMAIL) && defined(SENDMAILFLAGS)
  34.     char tmp[256];
  35.  
  36.     sprintf(tmp, "%s %s", SENDMAIL, SENDMAILFLAGS);
  37.     return(cpystr(tmp));
  38. #else
  39.     strcpy(errbuf, "No default posting command.");
  40.     return(NULL);
  41. #endif
  42. }
  43.  
  44.  
  45.  
  46. /*----------------------------------------------------------------------
  47.    Hand off given message to local posting agent
  48.  
  49.   Args: envelope -- The envelope for the BCC and debugging
  50.         header   -- The text of the message header
  51.         errbuf   -- buffer for reporting errors (assumed non-NULL)
  52.      
  53.    ----*/
  54. int
  55. mta_handoff(header, body, errbuf)
  56.     METAENV    *header;
  57.     BODY       *body;
  58.     char       *errbuf;
  59. {
  60.     char cmd_buf[256], *cmd = NULL;
  61.  
  62.     /*
  63.      * A bit of complicated policy implemented here.
  64.      * There are two posting variables sendmail-path and smtp-server.
  65.      * Precedence is in that order.
  66.      * They can be set one of 4 ways: fixed, command-line, user, or globally.
  67.      * Precedence is in that order.
  68.      * Said differently, the order goes something like what's below.
  69.      * 
  70.      * NOTE: the fixed/command-line/user precendence handling is also
  71.      *         indicated by what's pointed to by ps_global->VAR_*, but since
  72.      *         that also includes the global defaults, it's not sufficient.
  73.      */
  74.  
  75.     if(ps_global->FIX_SENDMAIL_PATH
  76.        && ps_global->FIX_SENDMAIL_PATH[0]){
  77.     cmd = ps_global->FIX_SENDMAIL_PATH;
  78.     }
  79.     else if(!(ps_global->FIX_SMTP_SERVER
  80.           && ps_global->FIX_SMTP_SERVER[0])){
  81.     if(ps_global->COM_SENDMAIL_PATH
  82.        && ps_global->COM_SENDMAIL_PATH[0]){
  83.         cmd = ps_global->COM_SENDMAIL_PATH;
  84.     }
  85.     else if(!(ps_global->COM_SMTP_SERVER
  86.           && ps_global->COM_SMTP_SERVER[0])){
  87.         if(ps_global->USR_SENDMAIL_PATH
  88.            && ps_global->USR_SENDMAIL_PATH[0]){
  89.         cmd = ps_global->USR_SENDMAIL_PATH;
  90.         }
  91.         else if(!(ps_global->USR_SMTP_SERVER
  92.               && ps_global->USR_SMTP_SERVER[0])){
  93.         if(ps_global->GLO_SENDMAIL_PATH
  94.            && ps_global->GLO_SENDMAIL_PATH[0]){
  95.             cmd = ps_global->GLO_SENDMAIL_PATH;
  96.         }
  97. #ifdef    DF_SENDMAIL_PATH
  98.         /*
  99.          * This defines the default method of posting.  So,
  100.          * unless we're told otherwise use it...
  101.          */
  102.         else if(!(ps_global->GLO_SMTP_SERVER
  103.               && ps_global->GLO_SMTP_SERVER[0])){
  104.             strcpy(cmd = cmd_buf, DF_SENDMAIL_PATH);
  105.         }
  106. #endif
  107.         }
  108.     }
  109.     }
  110.  
  111.     *errbuf = '\0';
  112.     if(cmd){
  113.     dprint(4, (debugfile, "call_mailer via cmd: %s\n", cmd));
  114.  
  115.     (void) mta_parse_post(header, body, cmd, errbuf);
  116.     return(1);
  117.     }
  118.     else
  119.       return(0);
  120. }
  121.  
  122.  
  123.  
  124. /*----------------------------------------------------------------------
  125.    Hand off given message to local posting agent
  126.  
  127.   Args: envelope -- The envelope for the BCC and debugging
  128.         header   -- The text of the message header
  129.         errbuf   -- buffer for reporting errors (assumed non-NULL)
  130.      
  131.   Fork off mailer process and pipe the message into it
  132.   Called to post news via Inews when NNTP is unavailable
  133.   
  134.    ----*/
  135. char *
  136. post_handoff(header, body, errbuf)
  137.     METAENV    *header;
  138.     BODY       *body;
  139.     char       *errbuf;
  140. {
  141.     char *err = NULL;
  142. #ifdef    SENDNEWS
  143.     char *s;
  144.  
  145.     if(s = strstr(header->env->date," (")) /* fix the date format for news */
  146.       *s = '\0';
  147.  
  148.     if(err = mta_parse_post(header, body, SENDNEWS, errbuf))
  149.       sprintf(err = errbuf, "News not posted: \"%s\": %s", SENDNEWS, err);
  150.  
  151.     if(s)
  152.       *s = ' ';                /* restore the date */
  153.  
  154. #else /* !SENDNEWS */  /* this is the default case */
  155.     sprintf(err = errbuf, "Can't post, NNTP-server must be defined!");
  156. #endif /* !SENDNEWS */
  157.     return(err);
  158. }
  159.  
  160.  
  161.  
  162. /*----------------------------------------------------------------------
  163.    Hand off message to local MTA; it parses recipients from 822 header
  164.  
  165.   Args: header -- struct containing header data
  166.         body  -- struct containing message body data
  167.     cmd -- command to use for handoff (%s says where file should go)
  168.     errs -- pointer to buf to hold errors
  169.  
  170.    ----*/
  171. static char *
  172. mta_parse_post(header, body, cmd, errs)
  173.     METAENV *header;
  174.     BODY    *body;
  175.     char    *cmd;
  176.     char    *errs;
  177. {
  178.     char   *result = NULL;
  179.     int     rv;
  180.     PIPE_S *pipe;
  181.  
  182.     dprint(1, (debugfile, "=== mta_parse_post(%s) ===\n", cmd));
  183.  
  184.     if(pipe = open_system_pipe(cmd, &result, NULL,
  185.              PIPE_STDERR|PIPE_WRITE|PIPE_PROT|PIPE_NOSHELL|PIPE_DESC)){
  186.     if(!pine_rfc822_output(header, body, pine_pipe_soutr_nl,
  187.                    (TCPSTREAM *) pipe))
  188.       strcpy(errs, "Error posting.");
  189.  
  190.     if(close_system_pipe(&pipe) && !*errs){
  191.         sprintf(errs, "Posting program %s returned error", cmd);
  192.         if(result)
  193.           display_output_file(result, "POSTING ERRORS", errs);
  194.     }
  195.     }
  196.     else
  197.       sprintf(errs, "Error running \"%s\"", cmd);
  198.  
  199.     if(result){
  200.     unlink(result);
  201.     fs_give((void **)&result);
  202.     }
  203.  
  204.     return(*errs ? errs : NULL);
  205. }
  206.  
  207.  
  208. /* 
  209.  * pine_pipe_soutr - Replacement for tcp_soutr that writes one of our
  210.  *             pipes rather than a tcp stream
  211.  */
  212. static long
  213. pine_pipe_soutr_nl (stream,s)
  214.      void *stream;
  215.      char *s;
  216. {
  217.     long    rv = T;
  218.     char   *p;
  219.     size_t  n;
  220.  
  221.     while(*s && rv){
  222.     if(n = (p = strstr(s, "\015\012")) ? p - s : strlen(s))
  223.       while((rv = write(((PIPE_S *)stream)->out.d, s, n)) != n)
  224.         if(rv < 0){
  225.         if(errno != EINTR){
  226.             rv = 0;
  227.             break;
  228.         }
  229.         }
  230.         else{
  231.         s += rv;
  232.         n -= rv;
  233.         }
  234.  
  235.     if(p && rv){
  236.         s = p + 2;            /* write UNIX EOL */
  237.         while((rv = write(((PIPE_S *)stream)->out.d,"\n",1)) != 1)
  238.           if(rv < 0 && errno != EINTR){
  239.           rv = 0;
  240.           break;
  241.           }
  242.     }
  243.     else
  244.       break;
  245.     }
  246.  
  247.     return(rv);
  248. }
  249.